﻿; (function ($, window, document, undefined) {
    var pluginName = 'ajaxHandler',
        defaults = {
            dataType: 'html',
            ajaxType: 'GET',
            useWaiting: false,
            contentType: 'application/x-www-form-urlencoded',
            async: false,
            cache: false,
            traditional: false,
            autoLoad: true,
            validate: function () { return true; }
        };

    // The actual plugin constructor
    function Plugin(element, options) {
        this.el = element;
        this.opt = $.extend({}, defaults, options);
        this.$el = $(this.el);

        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }

    /**
    * Initialize the Ajax handler by binding the HTML element to the 'click' event
    * and calling the 'load' method with the specificed parameters.
    * @method init
    * @member ajaxHandler
    */
    Plugin.prototype.init = function () {
        var that = this;

        //window.log(this._name + '.init() ' + that.el.id);
        $.each(this.opt, function (key, value) {
            //window.log(that._name + '.init() options:' + key + ' "' + value + '"');
        });

        // Bind the specified HTML element to the load method
        //window.log(this._name + '.init() binding ' + this.el.id);
        if (this.$el.is('a')) {
            this.$el.on('click', function (e) {
                e.preventDefault();
                //window.log(that._name + '.init() ' + that.el.id + '.click()');
                if (typeof (that.opt.urlAction) == 'undefined') {
                    that.opt.urlAction = that.el.href;
                    //window.log(that._name + '.init() property "urlAction" is empty, automatically detect href attribute=' + that.opt.urlAction);
                }
                //window.log(that._name + '.init() ' + that.el.id + '.click() with urlAction=' + that.opt.urlAction);
                if (that.opt.validate()) {

                    that.load(that.opt);
                }
            });
        } else {
            //window.log(that._name + '.init() ' + that.el.id + '.post()');
            if (typeof (that.opt.urlAction) == 'undefined') {
                if (typeof (that.el.action) != 'undefined') {
                    that.opt.urlAction = that.el.action;
                    //window.log(that._name + '.init() property "urlAction" is empty, automatically detect action attribute=' + that.opt.urlAction);
                } else {
                   // window.log(that._name + '.init() property "urlAction" is empty as well as href/form action, exiting...');
                    return false;
                }
            }
           // window.log(that._name + '.init() ' + that.el.id + '.post() with urlAction=' + that.opt.urlAction);
            if (that.opt.autoLoad === true) {
                that.load(that.opt);
            }
        }
    };

    /**
    * Send the data to the Controller with the specified parameters
    * while hidding the viewError and viewSuccess and showing the viewLoading. 
    * If an error occured, the error message will be displayed in the viewError. 
    * If the Ajax call succeeded, the results will be displayed in the viewSuccess.
    * @method load
    * @public
    * @member ajaxHandler
    */
    Plugin.prototype.load = function (options) {
        var that = this;

        if (options.useWaiting) {
            $(that.el).waitingHandler();
        }
        //window.log(this._name + '.load()');
        //window.log(this._name + '.load() loading ' + options.urlAction);

        $.each(options, function (key, value) {
           // window.log(that._name + '.load() options:' + key + ' "' + value + '"');
        });

        $.ajax({
            url: options.urlAction,
            data: options.ajaxData,
            dataType: options.dataType,
            contentType: options.contentType,
            traditional: options.traditional,
            type: options.ajaxType,
            async: options.async,
            cache: options.cache,
            beforeSend: function () {
                //window.log(that._name + '.load() beforeSend');
                if (typeof (options.viewError) != 'undefined') {
                   // window.log(that._name + '.load() hide #' + options.viewError);
                    $('#' + options.viewError).hide();
                    if (typeof (options.viewErrorContainer) != 'undefined') {
                        $('#' + options.viewErrorContainer).hide();
                    }
                }
                if (typeof (options.viewSuccess) != 'undefined') {
                    //window.log(that._name + '.load() hide #' + options.viewSuccess);
                    $('#' + options.viewSuccess).hide();
                }
                if (typeof (options.viewLoading) != 'undefined') {
                   // window.log(that._name + '.load() show #' + options.viewLoading);
                    $('#' + options.viewLoading).show();
                }
                if (typeof (options.beforeSend) != 'undefined') {
                   // window.log(that._name + '.load() additional beforeSend');
                    options.beforeSend();
                }
            },
            success: function (data) {
                //window.log(that._name + '.load() success');
                if (typeof (options.viewSuccess) != 'undefined') {
                    //window.log(that._name + '.load() success data into #' + options.viewSuccess);
                    $('#' + options.viewSuccess).html(data);
                    //window.log(that._name + '.load() success show #' + options.viewSuccess);
                    $('#' + options.viewSuccess).show();
                }
                if (typeof (options.onSuccess) != 'undefined') {
                   // window.log(that._name + '.load() additional success');
                    options.onSuccess(data);
                }
            },
            error: function (jqXhr, textStatus, errorThrown) {
                //window.log(that._name + '.load() error');
                //window.log(that._name + '.load() error ' + jqXhr.message + ', ' + textStatus + ', ' + errorThrown);
                var mess;
                switch (jqXhr.status) {
                    case 401:
                        mess = l10n.ajaxErrorUnauthorized;
                        break;
                    case 403:
                        mess = l10n.ajaxErrorForbidden;
                        break;
                    case 404:
                        mess = l10n.ajaxErrorNotFound;
                        break;
                    case 408:
                        mess = l10n.ajaxErrorTimeout;
                        break;
                    case 500:
                        mess = JSON.parse(jqXhr.responseText);
                        mess = mess.message;
                        break;
                    default:
                        mess = jqXhr.responseText;
                }
                if (typeof (options.viewSuccess) != 'undefined') {
                    //window.log(that._name + '.load() error hide #' + options.viewSuccess);
                    $('#' + options.viewSuccess).hide();
                }
                if (typeof (options.viewError) != 'undefined') {
                   // window.log(that._name + '.load() error data into #' + options.viewError);
                    if (typeof (options.viewErrorContainer) != 'undefined') { //usefull?
                        $('#' + options.viewErrorContainer).show();
                    }
                    $('#' + options.viewError).html(mess);
                    $('#' + options.viewError).show();
                }
                if (typeof (options.onError) != 'undefined') {
                    //window.log(that._name + '.load() additional onError');
                    options.onError(jqXhr, textStatus, errorThrown);
                }
            },
            complete: function () {
                if (options.useWaiting) {
                    $(that.el).data('waitingPlugin').closed();
                }

                //window.log(that._name + '.load() complete');
                if (typeof (options.viewLoading) != 'undefined') {
                    //window.log(that._name + '.load() complete hide #' + options.viewLoading);
                    $('#' + options.viewLoading).hide();
                }
                if (typeof (options.onComplete) != 'undefined') {
                    //window.log(that._name + '.load() additional onComplete');
                    options.onComplete();
                }
            }
        });
    };

    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
            } else {
                var that = $.data(this, 'plugin_' + pluginName);
                var opts = $.extend({}, that.opt, options);
                that.load(opts);
            }
        });
    };

})(jQuery, window, document);